从业开始Maven就一直在用,但没有系统地去学习,这两天搜了一下关于Maven的书籍,比较少而且时间也比较长了。浏览了下官网,有个索引页面写的挺清楚的,所以就将其作为学习教材,采用不完全翻译的方式记录下来。仅作用于个人学习、以及分享,如涉及到版权问题,将立即停止更新。
安装
关于Maven的安装,参照官网。本人当前安装的环境如下:
|
|
如上mvn --version
是我们使用Maven的第一命令,如要查询所有命令可以通过mvn --help
输出。
创建一个项目
在命令行中执行如下命令来创建一个项目:
|
|
成功之后会在当前文件夹生成一个与artifactId同名的目录,即my-app。通常情况下,这一步通过IDEA里提供的可视界面来完成。my-app下的组织结构相信大家都非常清楚了,就没必要解释了,有需要的话可以参照官网标准目录布局的介绍。上述命令执行了一个Maven的行为:archetype:generate,并且将各种参数传递给该行为。前缀archetype是提供行为的插件,上述行为的意思是基于maven-archetype-quickstart原型创建一个简单的项目。其中pom.xml还是有必要来看下:
|
|
下面列出pom.xml每个标签的含义:
- project 这是pom.xml文件的顶级元素
- modelVersion 该元素指定POM使用的对象模型的版本,该属性很少更改
- groupId 该元素指定创建项目的组织的唯一标识符。groupId是项目的关键标识符之一,通常设置成组织的域名
- artifactId 可以理解为该项目的名称,打包出来的文件会使用到该名称
- packaging 该项目使用的包类型,不仅仅是打包的类型,如果不写则默认为jar
- version 指定项目的版本,打包出来的文件会使用到该属性
- name 项目的显示名称
- url 指定项目生成的site的url
- description 项目的描述信息
项目编译
执行如下命令:
|
|
编译后的文件生成在target/classes目录下。
项目打包
执行如下命令:
|
|
打包成功后会在target目录下生成jar文件。和上面执行命令mvn archetype:generate
不同,该命令表示一个阶段,而不是一个行为目标。阶段是构建生命周期中的一个步骤,是有序序列中的其中一个。当给定一个阶段时,Maven将执行序列中的每个阶段,直到包括定义的阶段为止。例如,如果执行compile阶段,实际执行的阶段将是:
- validate
- generate-sources
- process-sources
- generate-resources
- process-resources
- compile
可以使用如下命令测试生成的jar:
|
|
稍微解释下上面的命令,-cp指定类运行所依赖其他类的路径,com.mycompany.app.App表示要运行的类,将会执行其定义的入口方法main。
运行Maven工具
Maven阶段
如下虽然不是一个全面的列表,但是这些是最常见的执行的默认生命周期阶段。
- validate:验证项目是否正确,所有的必要信息是否都可用
- compile:编译项目的源代码
- test:使用合适的单元测试框架测试编译后的源代码。这些测试不需要被打包或部署
- package:将编译后的代码以其可分发的格式打包,例如JAR
- integration-test:如果需要,将包处理并部署到可以运行集成测试的环境中
- verify:运行任何检查以验证包是否有效并满足质量标准
- install:将包安装到本地存储库中,作为本地其他项目的依赖项使用
- deploy:在集成或发布环境中操作,将最终包复制到远程存储库,以便与其他开发人员和项目共享
除了上述默认列表之外,还有两个Maven生命周期值得注意。他们是:
- clean:清理以前构建的内容
- site:为该项目生成站点文档
阶段实际上映射到底层行为。每个阶段执行的具体行为取决于项目的打包类型。例如,如果项目类型是jar, package将执行jar:jar;如果项目类型是war,则执行war:war。
有趣的是,阶段和目标可以是按顺序执行的,比如:mvn clean dependency:copy-dependencies package
。此命令将清理项目、复制依赖项并打包项目按顺序执行。
生成站点
|
|
成功之后将会在target目录下生成site目录,打开index.html可以看到项目的一些信息,比如依赖、使用的插件之类。
SNAPSHOT
看下之前打包的jar文件,其名为my-app-1.0-SNAPSHOT.jar,这里的SNAPSHOT指的是开发分支中的最新代码,不能保证代码是稳定的或不变的。相反release版本是不变的。换句话说,快照版本是最终“发布”版本之前的“开发”版本。快照比它的发布“更早”。
在发布过程中x.y-SNAPSHOT将变成 x.y,同时发布过程还将开发版本增加到x.(y+1)-SNAPSHOT。例如,版本1.0-SNAPSHOT作为版本1.0发布,新的开发版本将变成1.1-SNAPSHOT。
使用插件
每当想为Maven项目定制构建时,都可以通过添加或重新配置插件来完成。
下面的例子将配置Java编译器以允许JDK 5.0源代码,将如下代码添加的pom文件中:
|
|
我们可以看到Maven中的所有插件看起来都很像一个依赖项——在某些方面确实如此。这个插件将自动下载和使用,如果不指定版本将使用最新的,否则使用指定版本号的插件。
配置元素将给定的参数应用于编译器插件的每个行为。在上面的例子中,编译器插件已经作为构建过程的一部分使用了,这里只是更改了配置。还可以向流程中添加新的行为,并配置特定的行为。这里只是先了解下插件的概念,后面会再深入学习。
JAR中添加资源
另一种不需要对POM进行任何更改就可以满足的常见方式是,将资源打包到JAR文件中。对于这个常见任务,Maven再次依赖于标准目录布局,这意味着通过使用标准的Maven约定,将这些资源放在标准目录结构中来将其打包到jar中。其实也就是resources目录,目前这个目录默认没有创建出来,我们自行创建,然后在其中添加一个名为application.properties的文件。解压下打包的jar文件看看什么样:
|
|
可以看到在解压出来的根目录生成了application.properties文件,同时还有个 META-INF目录,这个是Maven自动生成的。关注下 MANIFEST.MF,该文件定义了与扩展和包相关的数据,其中有个Main-Class属性,配置正确的话,可以打出一个可执行jar包。下面我们通过修改pom.xml的如下插件来实现该功能:
|
|
修改完之后来测试下:
|
|
过滤资源文件
有时资源文件需要包含只能在构建时提供的值。要在Maven中实现这一点,可以使用${
直接使用pom文件中的标签属性值
要在复制时使用Maven筛选资源,只需将筛选设置为true,作用于pom.xml中的资源目录:
|
|
下面修改之前添加的application.properties文件,在其中添加获取pom.xml中project的一些信息:
|
|
可以执行以下命令进行测试,process-resources是复制和筛选资源的构建生命周期阶段。
|
|
引用外部文件的属性值
要引用外部文件中定义的属性,需要在pom.xml中添加对该外部文件的引用。首先,我们创建一个外部属性文件,并将其命名为src/main/filters/filter.properties:
|
|
filters是Maven的目录,作用就是存放资源文件。接下来,我们将在pom.xml中添加对这个新文件的引用:
|
|
最后修改application.properties,添加如下:
|
|
测试下:
|
|
在pom文件中自定义属性
作为定义my.filter的替代方法,可以直接在pom的properties部分中定义它:
|
|
修改application.properties,添加如下:
|
|
测试:
|
|
获取系统属性
过滤资源还可以从系统属性中获取值,无论是Java的内置属性或者是标准Java -D参数在命令行上定义的属性。修改application.properties文件,添加如下内容:
|
|
下面进行测试:
|
|
本篇是一个简单的Quick Start,后面将会继续深入。